/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.evangelion.core.controller;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;

import org.primefaces.model.DefaultStreamedContent;

import com.evangelion.core.bean.Declaracion;
import com.evangelion.core.bean.Movimiento;
import com.evangelion.core.bean.MovimientoAux;
import com.evangelion.core.bean.Seccione;
import com.evangelion.core.bean.Usuario;
import com.evangelion.core.daoImpl.ConnectionUtil;
import com.evangelion.core.pojo.IvaSum;
import com.evangelion.core.utils.MensajesFace;
import com.evangelion.core.utils.SeccionConverter;

/**
 *
 * @author Usuario
 */
@ManagedBean
@ViewScoped
public class InformeController extends MensajesFace implements Serializable {

    private String valorBusqueda;
    private Date fechaI;
    private Date fechaF;
    private Date fechaIn;
    private Date fechaFn;
    private Date fechaIiva;
    private Date fechaFiva;
    private List<Movimiento> listaMovimiento;
    private Usuario usu;
    private Seccione seccion;
    private List<Seccione> listaSeccion;
    private DefaultStreamedContent dc;

    private List<MovimientoAux> listaDeclaracion;
    private Double devolver;
    private Double ingresar;
    private Declaracion declaracion;
    private List<Movimiento> listaFacturaIngreso;
    private List<MovimientoAux> listaFactIngAux;
    private List<Declaracion> listaDeclaciones;

    private boolean enableVistaPre;
    private boolean enableGuardar;
    private double valorDeclaracion;
    //String diario;
    private List<IvaSum> ivaSums;

    @PostConstruct
    public void init() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        HttpSession httpSession = request.getSession(false);
        if (httpSession != null) {
            usu = (Usuario) httpSession.getAttribute("UserSession");
        }
        listaMovimiento = new ArrayList<Movimiento>();
        listaMovimiento = movimientoService.searchByApunte(seccion, "", new Date(), new Date());
        listaSeccion = SeccionConverter.linkTypesDB;
        listaDeclaracion = new ArrayList<MovimientoAux>();
        declaracion = new Declaracion();
        declaracion.setAnno(0);
        declaracion.setTrimestre(0);
        listaDeclaciones = new ArrayList<Declaracion>();
        listaFactIngAux = new ArrayList<MovimientoAux>();
        enableGuardar = false;
        enableVistaPre = false;
        listaDeclaciones = declaracionService.listDeclaraciones("Facturacion");
    }

    public void buscarFacturaciones() {
        Declaracion decl = declaracionService.findDeclaracion(declaracion.getAnno(), declaracion.getTrimestre());
        if (decl != null) {
            declaracion = decl;
            msgAdvertencia("Este trimestre ya se encuentra registrado");
            enableVistaPre = true;
            enableGuardar = false;
            return;
        }
        declaracion.setMovimientoAuxList(new ArrayList<MovimientoAux>());
        Date fechaInicio = new Date();
        Date fechaFin = new Date();
        if (declaracion.getAnno() == 0) {
            msgAdvertencia("Seleccione un a�o");
            return;
        }
        if (declaracion.getTrimestre() == 0) {
            msgAdvertencia("Seleccione un trimestre");
            return;
        }
        Calendar calendar = Calendar.getInstance();
        if (declaracion.getTrimestre() == 1) {
            calendar.set(declaracion.getAnno(), 0, 01);
            fechaInicio = calendar.getTime();
            calendar.set(declaracion.getAnno(), 2, 31);
            fechaFin = calendar.getTime();
        }
        if (declaracion.getTrimestre() == 2) {
            calendar.set(declaracion.getAnno(), 3, 01);
            fechaInicio = calendar.getTime();
            calendar.set(declaracion.getAnno(), 5, 30);
            fechaFin = calendar.getTime();
        }
        if (declaracion.getTrimestre() == 3) {
            calendar.set(declaracion.getAnno(), 6, 01);
            fechaInicio = calendar.getTime();
            calendar.set(declaracion.getAnno(), 9, 30);
            fechaFin = calendar.getTime();
        }
        if (declaracion.getTrimestre() == 4) {
            calendar.set(declaracion.getAnno(), 10, 01);
            fechaInicio = calendar.getTime();
            calendar.set(declaracion.getAnno(), 12, 31);
            fechaFin = calendar.getTime();
        }
        listaFacturaIngreso = movimientoService.findListFacturasIngreso(null, fechaInicio, fechaFin);
        declaracion.setValorTotalFactura(movimientoService.findSumaFacturasIngreso(null, fechaInicio, fechaFin));
        declaracion.setValorFactDescontar(movimientoService.findSumaFacturasAdeclarar(null, fechaInicio, fechaFin));
        for (Movimiento movimiento : listaFacturaIngreso) {
            MovimientoAux movaux = new MovimientoAux();
            movaux.setFecha(movimiento.getFecha());
            movaux.setConcepto(movimiento.getConcepto().toUpperCase());
            movaux.setDocumento(movimiento.getDocumento());
            movaux.setDebe(movimiento.getDebe());
            movaux.setHaber(movimiento.getHaber());
            movaux.setIva(movimiento.getIva());
            movaux.setImpIVA(movimiento.getImpIVA());
            movaux.setBc(movimiento.getBc());
            movaux.setDescuentoDeclaracion(0.0);
            movaux.setTotal(movimiento.getTotal());
            movaux.setSeccion(movimiento.getSeccion());
            movaux.setCliente(movimiento.getCliente());
            movaux.setDeclaracion(declaracion);
            listaFactIngAux.add(movaux);
        }
        declaracion.setMovimientoAuxList(listaFactIngAux);
        if (listaFactIngAux.size() <= 0 || declaracion.getValorFactDescontar() <= 0) {
            enableGuardar = false;
            msgAdvertencia("No existe facturas a descontar");
        }
        enableVistaPre = true;
        enableGuardar = false;
    }

    public void save() {
        if (valorDeclaracion == declaracion.getValorDeclarado()) {
            declaracion.setFecha(new Date());
            declaracion.setFechadeclaracion(new Date());
            declaracion.setNvoValorFactura(declaracion.getValorDeclarado());
            declaracion.setTipo("Facturacion");
            declaracionService.save(declaracion);
            init();
            msgCambiosGuardados();
        } else {
            msgInfoError("Ha modificado el valor del Imp. a declarar, Seleccion nuevamente vistaprevia");
            enableGuardar = false;
        }
    }

    public void searchDeclaracion() {
        listaDeclaracion = movimientoService.searchByHecho(seccion, valorBusqueda, fechaIn, fechaFn);
    }

    public void prueba(int i, Date fi, Date ff) {
        String archivo = "reporteMovimiento.jasper";
        Map parameters = new HashMap();
        parameters.put("apunte", i);
        parameters.put("fechaI", fi);
        parameters.put("fechaF", ff);
        printpdf(parameters, archivo);

    }

    public void search() {
        listaMovimiento = movimientoService.searchByApunte(seccion, valorBusqueda, fechaI, fechaF);
    }

    public void searchIva() {
//        if (diario != null) {
//            if (!diario.equals("")) {
        //objIvaEgreso =
        List<IvaSum> isList = factureService.ivaIngresos(fechaIiva, fechaFiva, seccion);

        ivaSums = new ArrayList<IvaSum>();
        for (int i = 0; i < 4; i++) {
            ivaSums.add(new IvaSum());
        }

        for (IvaSum is : isList) {
            if (Double.valueOf(0).equals(is.getIva())) {
                ivaSums.set(0, is);
            } else if (Double.valueOf(4).equals(is.getIva())) {
                ivaSums.set(1, is);
            } else if (Double.valueOf(10).equals(is.getIva())) {
                ivaSums.set(2, is);
            } else if (Double.valueOf(21).equals(is.getIva())) {
                ivaSums.set(3, is);
            }
        }

//
//                Double ivaIngreso = ((Double) objIvaIngreso[1] * 0.04 + (Double) objIvaIngreso[2] * 0.10 + (Double) objIvaIngreso[3] * 0.21);
//                Double ivaEgreso = ((Double) objIvaEgreso[1] * 0.04 + (Double) objIvaEgreso[2] * 0.10 + (Double) objIvaEgreso[3] * 0.21);
//
        ingresar = ivaSums.get(3).getHaberSum() * 0.21 - ivaSums.get(3).getDebeSum() * 0.21;
        devolver = ivaSums.get(3).getDebeSum() * 0.21 - ivaSums.get(3).getHaberSum() * 0.21;
        if (devolver < 0) {
            devolver = 0.00;
        }
        if (ingresar < 0) {
            ingresar = 0.00;
        }
//            }
//        }
    }

    public void printpdf(Map parameters, String archivo) {
        try {
            Connection conexion = connectionUtil.getConnection();
            String urlMaster = ConnectionUtil.getServletContext().getRealPath(REPORT_FOLDER + archivo);
            JasperReport reporteMaster = null;
            try {
                reporteMaster = (JasperReport) JRLoader.loadObject(urlMaster);
            } catch (Exception e) {
                e.printStackTrace();
            }
            JasperPrint print = null;
            print = JasperFillManager.fillReport(reporteMaster, parameters, conexion);
            byte[] bytes = JasperExportManager.exportReportToPdf(print);
            if (bytes.length >= 1211 && bytes.length <= 1608) {
                dc = null;
                msgValidacion("El reporte no genero ningun resultado");
            } else {
                InputStream stream = new ByteArrayInputStream(bytes);
                dc = new DefaultStreamedContent(stream, "application/pdf", "Archivo.pdf");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void vistaPrevia() {
        enableGuardar = false;
        valorDeclaracion = declaracion.getValorDeclarado();
        listaFactIngAux = new ArrayList<MovimientoAux>();
        if (declaracion.getId() != null) {
            listaFactIngAux = declaracion.getMovimientoAuxList();
        }
        if ((declaracion.getValorTotalFactura() - declaracion.getValorDeclarado()) > 0) {
            double porcentajeDesc = ((declaracion.getValorTotalFactura() - declaracion.getValorDeclarado()) / declaracion.getValorFactDescontar());
            for (MovimientoAux movaux : declaracion.getMovimientoAuxList()) {
                if (movaux.getConcepto().toUpperCase().contains("PRACTIC")) {
                    movaux.setDescuentoDeclaracion(movaux.getTotal() * porcentajeDesc);
                }
            }
            enableGuardar = true;
        } else {
            msgAdvertencia("No hay valor a descontar");
        }
    }

    public List<Movimiento> getListaFacturaIngreso() {
        return listaFacturaIngreso;
    }

    public void setListaFacturaIngreso(List<Movimiento> listaFacturaIngreso) {
        this.listaFacturaIngreso = listaFacturaIngreso;
    }

    public Declaracion getDeclaracion() {
        return declaracion;
    }

    public void setDeclaracion(Declaracion declaracion) {
        this.declaracion = declaracion;
    }

    public boolean isEnableVistaPre() {
        return enableVistaPre;
    }

    public void setEnableVistaPre(boolean enableVistaPre) {
        this.enableVistaPre = enableVistaPre;
    }

    public boolean isEnableGuardar() {
        return enableGuardar;
    }

    public void setEnableGuardar(boolean enableGuardar) {
        this.enableGuardar = enableGuardar;
    }

    public List<Declaracion> getListaDeclaciones() {
        return listaDeclaciones;
    }

    public void setListaDeclaciones(List<Declaracion> listaDeclaciones) {
        this.listaDeclaciones = listaDeclaciones;
    }

    public DefaultStreamedContent getDc() {
        return dc;
    }

    public void setDc(DefaultStreamedContent dc) {
        this.dc = dc;
    }

    public Date getFechaI() {
        return fechaI;
    }

    public void setFechaI(Date fechaI) {
        this.fechaI = fechaI;
    }

    public Date getFechaF() {
        return fechaF;
    }

    public void setFechaF(Date fechaF) {
        this.fechaF = fechaF;
    }

    public String getValorBusqueda() {
        return valorBusqueda;
    }

    public void setValorBusqueda(String valorBusqueda) {
        this.valorBusqueda = valorBusqueda;
    }

    public List<Movimiento> getListaMovimiento() {
        return listaMovimiento;
    }

    public void setListaMovimiento(List<Movimiento> listaMovimiento) {
        this.listaMovimiento = listaMovimiento;
    }

    public List<Seccione> getListaSeccion() {
        return listaSeccion;
    }

    public void setListaSeccion(List<Seccione> listaSeccion) {
        this.listaSeccion = listaSeccion;
    }

    public Seccione getSeccion() {
        return seccion;
    }

    public void setSeccion(Seccione seccion) {
        this.seccion = seccion;
    }

    public Date getFechaIiva() {
        return fechaIiva;
    }

    public void setFechaIiva(Date fechaIiva) {
        this.fechaIiva = fechaIiva;
    }

    public Date getFechaFiva() {
        return fechaFiva;
    }

    public void setFechaFiva(Date fechaFiva) {
        this.fechaFiva = fechaFiva;
    }

    public Date getFechaIn() {
        return fechaIn;
    }

    public void setFechaIn(Date fechaIn) {
        this.fechaIn = fechaIn;
    }

    public Date getFechaFn() {
        return fechaFn;
    }

    public void setFechaFn(Date fechaFn) {
        this.fechaFn = fechaFn;
    }

    public List<MovimientoAux> getListaDeclaracion() {
        return listaDeclaracion;
    }

    public void setListaDeclaracion(List<MovimientoAux> listaDeclaracion) {
        this.listaDeclaracion = listaDeclaracion;
    }

//    public String getDiario() {
//        return diario;
//    }
//
//    public void setDiario(String diario) {
//        this.diario = diario;
//    }
    public List<IvaSum> getIvaSums() {
        return ivaSums;
    }

    public void setIvaSums(List<IvaSum> ivaSums) {
        this.ivaSums = ivaSums;
    }

    public Double getDevolver() {
        return devolver;
    }

    public void setDevolver(Double devolver) {
        this.devolver = devolver;
    }

    public Double getIngresar() {
        return ingresar;
    }

    public void setIngresar(Double ingresar) {
        this.ingresar = ingresar;
    }
}
